home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 8 / FM Towns Free Software Collection 8.iso / t_os / wink24h / src / xmodem.c < prev    next >
Text File  |  1994-06-01  |  23KB  |  984 lines

  1.  
  2. #define SOH     '\x01'
  3. #define STX     '\x02'
  4. #define EOT     '\x04'
  5. #define ACK     '\x06'
  6. #define NAK     '\x15'
  7. #define CAN     '\x18'
  8. #define CRC     '\x43'
  9. #define    CR    '\x0D'
  10.  
  11. #define    XM_FILE        0
  12. #define    XM_FSIZE    2
  13. #define    XM_TBLK        3
  14. #define    XM_SSIZE    4
  15. #define    XM_SBLK        5
  16. #define    XM_RSIZE    6
  17. #define    XM_RBLK        7
  18. #define    XM_TMOVR    8
  19. #define    XM_RETRY    9
  20. /* ------------XMODEM 1024/SUM/CRC 92/02/17 Pumpkin --------------- */
  21. #define    XM_ERTIME    10
  22. #define    XM_RATE        11
  23. #define    XM_MSG        12
  24. /*****
  25. #define    XM_MSG        10
  26. *****/
  27. /* ---------------------------------------------------------------- */
  28.  
  29. #define    DSP_WAIT    50000
  30.  
  31. int    Recive()
  32. {
  33.     int      ch;
  34.     unsigned int st;
  35.     time_t   s,n;
  36.  
  37.     if ( RSB_Receive(port,&ch,&st) == 0 )
  38.     return (ch & 0xff);
  39.  
  40.     time(&s);
  41.     do {
  42.     if ( RSB_Receive(port,&ch,&st) == 0 )
  43.         return (ch & 0xff);
  44.     time(&n);
  45.     } while ( (n - s) < 5 );
  46.  
  47.     return ERR;
  48. }
  49. static int  Recive_str(arg,n)
  50. UCHAR    *arg;
  51. int    n;
  52. {
  53.     int        ch;
  54.  
  55.     while ( n-- > 0 ) {
  56.         if ( (ch = Recive()) == ERR )
  57.         return ERR;
  58.     *(arg++) = ch;
  59.     }
  60.     return FALSE;
  61. }
  62.  
  63. /*************************************************
  64.    <<< X-Modem UpLoad Abort Hit ESC Key >>>
  65.  
  66. File Name    A:WINK.EXP
  67. File Size    xxxx        Total Block  xxxx
  68. Send Size    xxxx        Send Block   xxxx
  69. Recive Size  xxxx        Recive Block xxxx
  70. Time Over    xxxx        ReTry Count  xxxx
  71. Message      xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  72.  
  73. 012345678901234567890123456789012345678901234567890
  74. ***************************************************/
  75. void    Xmd_wind(md,file)
  76. char    *md,*file;
  77. {
  78.     int    i;
  79.     long   l;
  80.     char   tmp[160];
  81.     static char *menu[]={
  82.     "File Name",    "",
  83.     "File Size",    "Total Block",
  84.     "Send Size",    "Send Block",
  85.     "Recive Size",    "Recive Block",
  86.     "Time Over",    "ReTry Count",
  87. /* --------------XMODEM 1024/SUM/CRC 92/02/17 Pumpkin -------------- */
  88.     "Erapsed Time",    "Data Rate",
  89. /* ---------------------------------------------------------------- */
  90.     "Message",
  91.     NULL
  92.     };
  93.  
  94. /* --------------XMODEM 1024/SUM/CRC 92/02/17 Pumpkin --------------- */
  95.     Dmy_form(tmp,50,0x98,0x95,0x99); 
  96.     wrtstr(tmp,15,7,0x05);
  97.     Dmy_form(tmp,50,0x96,0x20,0x96); 
  98.     for ( i = 0 ; i < 10 ; i++ )
  99.         wrtstr(tmp,15,8+i,0x05);
  100.  
  101.     Dmy_form(tmp,50,0x9A,0x95,0x9B); 
  102.     wrtstr(tmp,15,17,0x05);
  103.  
  104.     sprintf(tmp,"<<< X/Y-Modem %s Abort Hit ESC Key >>>",md);
  105.     wrtstr(tmp,19,8,0x01);
  106. /*****
  107.     Dmy_form(tmp,50,0x98,0x95,0x99); 
  108.     wrtstr(tmp,15,7,0x05);
  109.  
  110.     Dmy_form(tmp,50,0x96,0x20,0x96); 
  111.     for ( i = 0 ; i < 9 ; i++ )
  112.         wrtstr(tmp,15,8+i,0x05);
  113.  
  114.     Dmy_form(tmp,50,0x9A,0x95,0x9B); 
  115.     wrtstr(tmp,15,17,0x05);
  116.  
  117.     sprintf(tmp,"<<< X-Modem %s Abort Hit ESC Key >>>",md);
  118.     wrtstr(tmp,20,8,0x01);
  119. *****/
  120. /* ---------------------------------------------------------------- */
  121.  
  122.     for ( i = 0 ; menu[i] != NULL ; i++ )
  123.     wrtstr(menu[i],17 + (i % 2) * 28,10 + i / 2,0x05);
  124.  
  125.     wrtstr(file,30,10,0x05);
  126. }
  127. void    Xmd_msg(msg)
  128. char    *msg;
  129. {
  130. /* -------------------- DATA RATE 92/02/17 Pumpkin ---------------- */
  131.     wrtstr(msg,30,16,0x05);
  132. /*****
  133.     wrtstr(msg,30,15,0x05);
  134. *****/
  135. /* ---------------------------------------------------------------- */
  136. }
  137. void    Xmd_val(no,val)
  138. int    no;
  139. long    val;
  140. {
  141.     char    tmp[40];
  142. /* -------------------- DATA RATE 92/02/17 Pumpkin ---------------- */
  143.     if (no == XM_ERTIME) {
  144.     sprintf(tmp,"%02ld:%02ld:%02ld",val/3600,(val%3600)/60,val%60);
  145.     } else {
  146.         sprintf(tmp,"%ld ",val);
  147.     }
  148. /*****
  149.     sprintf(tmp,"%ld",val);
  150. *****/
  151. /* ---------------------------------------------------------------- */
  152.     wrtstr(tmp,30 + (no % 2) * 28,10 + no / 2,0x05);
  153.  
  154. }
  155.  
  156. /* --------------XMODEM 1024/SUM/CRC 92/02/17 Pumpkin --------------- */
  157. int        crcmode=FALSE;
  158.  
  159. #define W    16    /* CRCビット数 */
  160. #define B    8     /* the number of bits per char */
  161. #define crctab crc_table
  162. extern unsigned short crctab[];
  163. /* ---------------------------------------------------------------- */
  164.  
  165. static int Send_blk(fp,bk,bufsize)
  166. FILE    *fp;
  167. int     bk;
  168. int    bufsize;
  169. {
  170.     int     i,j;
  171.     UCHAR   head[3];
  172.  
  173. /* --------------XMODEM 1024/SUM/CRC 92/02/17 Pumpkin -------------- */
  174.     unsigned short crcsum;
  175.     UCHAR   *p,tmp[1024];
  176.  
  177.     if (bufsize == 128) {
  178.         head[0]=SOH;
  179.     } else {
  180.         head[0]=STX;
  181.     }
  182.  
  183.     head[1]=bk;
  184.     head[2]=255-bk;
  185.  
  186.     if ( (i=fread(tmp,1,bufsize,fp)) <= 0 ) {
  187.     send_aux(EOT);
  188.         return ERR;
  189.     }
  190.  
  191.     for ( p=tmp+i ; i < bufsize ; i++ )
  192.         *(p++)='\0';
  193.  
  194.     for ( crcsum = j = i = 0 ; i < bufsize ; i++ ) {
  195.     if (crcmode==TRUE)  { /* CRC */
  196.             crcsum = (crcsum<<B) ^ crctab[(crcsum>>(W-B)) ^ tmp[i]];
  197.     } else {        /* checksum */
  198.          j += tmp[i]; j &= 0xff;
  199.     }
  200.     }
  201.  
  202.     send_str(head,3);
  203.     send_str(tmp,bufsize);
  204.     if (crcmode==TRUE)  { /* CRC */
  205.         send_aux(crcsum >> 8);
  206.         send_aux(crcsum & 255);
  207.     } else {        /* checksum */
  208.         send_aux(j);
  209.     }
  210.  
  211. /*******
  212.     UCHAR   *p,tmp[128];
  213.  
  214.     head[0]=SOH;
  215.     head[1]=bk;
  216.     head[2]=255-bk;
  217.  
  218.     if ( (i=fread(tmp,1,128,fp)) <= 0 ) {
  219.     send_aux(EOT);
  220.         return ERR;
  221.     }
  222.  
  223.     for ( p=tmp+i ; i < 128 ; i++ )
  224.         *(p++)='\0';
  225.     for ( j = i = 0 ; i < 128 ; i++,j &= 0xff )
  226.         j += tmp[i];
  227.  
  228.     send_str(head,3);
  229.     send_str(tmp,128);
  230.     send_aux(j);
  231. *******/
  232. /* ---------------------------------------------------------------- */
  233.  
  234.  
  235.     return FALSE;
  236. }
  237.  
  238.  
  239. /* --------------XMODEM 1024/SUM/CRC 92/02/17 Pumpkin --------------- */
  240. void    Up_Xmodem(file)
  241. char    *file;
  242. {
  243.     int     i,ch,bk,nk,ef;
  244.     unsigned int ec;
  245.     FILE    *fp;
  246.     long    size,remsize;
  247.     int        bufsize=128;
  248.     char    tmp[80];
  249.     time_t  fsttime,nowtime,*t=NULL;
  250.  
  251.     if (crcmode == TRUE) bufsize =1024;
  252.  
  253.     Xmd_wind("UpLoad",file);
  254.     if ( (fp = fopen(file,"rb")) == NULL ) {
  255.     Xmd_msg("File Not Found");
  256.     Soft_Timer(DSP_WAIT);
  257.     return;
  258.     }
  259.     fseek(fp,0L,2);
  260.     remsize = size = (long)ftell(fp);
  261.     fseek(fp,0L,0);
  262.     Xmd_val(XM_FSIZE,size);
  263.     i = size / bufsize;
  264.     i += ((size - i * bufsize)+127) / 128;
  265.     Xmd_val(XM_TBLK,i);
  266.     fsttime = time(t);
  267.  
  268.     for ( bk = 1, nk = 0, ef = FALSE, size = 0 ; ; ) {
  269.     if ( kbhit() != 0 ) {
  270.         ch = Get_key(&ec);
  271.         if ( ch == 0x1B || ec == 0x7200 ) {
  272.         Xmd_msg("Abort Xmodem Upload !!");
  273.             send_aux(CAN);
  274.         Soft_Timer(DSP_WAIT);
  275.         break;
  276.         }
  277.     }
  278.     for ( i = 0 ; i < 5 ; i++ ) {
  279.         if ( (ch = Recive()) != ERR ) 
  280.         break;
  281.         Xmd_val(XM_TMOVR,i);
  282.     }
  283.     if ( i >= 5 ) {
  284.         Xmd_msg("Time Over Aobrt !!");
  285.         Soft_Timer(DSP_WAIT);
  286.         break;
  287.     }
  288.     if ( ch == ACK) {
  289.         size += bufsize; remsize -= bufsize; nk = 0; bk++;
  290.  
  291.         if ( ef != FALSE ) {
  292.         Xmd_msg("End of Upload !!");
  293.         break;
  294.         }
  295.         if ( remsize < 0 && bufsize == 1024) {
  296.         remsize += bufsize;
  297.             bufsize = 128;
  298.         }
  299.  
  300.         if ( Send_blk(fp,bk,bufsize) != FALSE )
  301.         ef = TRUE;
  302.         else {
  303.         Xmd_val(XM_SSIZE,size + bufsize);
  304.         Xmd_val(XM_SBLK,bk);
  305.             nowtime = time(t);
  306.             if ((nowtime-fsttime) != 0) {
  307.                 Xmd_val(XM_RATE,(size+bufsize)/(nowtime-fsttime));
  308.             }
  309.         Xmd_val(XM_ERTIME,(nowtime-fsttime));
  310.         }
  311.     } else if ( ch == NAK  || ch == CRC ) {
  312.         if ( nk++ > 0 )
  313.         Xmd_val(XM_RETRY,nk);
  314.         fseek(fp,size,SEEK_SET);
  315.         if ( Send_blk(fp,bk,bufsize) != FALSE )
  316.         ef = TRUE;
  317.         else {
  318.         Xmd_val(XM_SSIZE,size + bufsize);
  319.         Xmd_val(XM_SBLK,bk);
  320.             nowtime = time(t);
  321.             if ((nowtime-fsttime) != 0) {
  322.                 Xmd_val(XM_RATE,(size+bufsize)/(nowtime-fsttime));
  323.             }
  324.         Xmd_val(XM_ERTIME,(nowtime-fsttime));
  325.         }
  326.     } else if ( ch == CAN ) {
  327.             Xmd_msg("Recive Cansel Code !!");
  328.         Soft_Timer(DSP_WAIT);
  329.             break;
  330.         }
  331.         if ( nk >= 5 ) {
  332.             Xmd_msg("ReTry Over Abort !!");
  333.         send_aux(CAN);
  334.         Soft_Timer(DSP_WAIT);
  335.         break;
  336.     }
  337.     }
  338.     fclose(fp);
  339. }
  340.  
  341. /**********
  342. void    Up_Xmodem(file)
  343. char    *file;
  344. {
  345.     int     i,ch,bk,nk,ef;
  346.     unsigned int ec;
  347.     FILE    *fp;
  348.     long    size;
  349.     char    tmp[80];
  350.  
  351.     Xmd_wind("UpLoad",file);
  352.     if ( (fp = fopen(file,"rb")) == NULL ) {
  353.     Xmd_msg("File Not Found");
  354.     Soft_Timer(DSP_WAIT);
  355.     return;
  356.     }
  357.     fseek(fp,0L,2);
  358.     size = (long)ftell(fp);
  359.     fseek(fp,0L,0);
  360.     Xmd_val(XM_FSIZE,size);
  361.     Xmd_val(XM_TBLK,(size + 127) / 128);
  362.  
  363.     for ( bk = 1, nk = 0, ef = FALSE, size = 0 ; ; ) {
  364.     if ( kbhit() != 0 ) {
  365.         ch = Get_key(&ec);
  366.         if ( ch == 0x1B || ec == 0x7200 ) {
  367.         Xmd_msg("Abort Xmodem Upload !!");
  368.             send_aux(CAN);
  369.         Soft_Timer(DSP_WAIT);
  370.         break;
  371.         }
  372.     }
  373.     for ( i = 0 ; i < 5 ; i++ ) {
  374.         if ( (ch = Recive()) != ERR ) 
  375.         break;
  376.         Xmd_val(XM_TMOVR,i);
  377.     }
  378.     if ( i >= 5 ) {
  379.         Xmd_msg("Time Over Aobrt !!");
  380.         Soft_Timer(DSP_WAIT);
  381.         break;
  382.     }
  383.     if ( ch == ACK ) {
  384.         size += 128; nk = 0; bk++;
  385.         if ( ef != FALSE ) {
  386.         Xmd_msg("End of Upload !!");
  387.         break;
  388.         }
  389.         if ( Send_blk(fp,bk) != FALSE )
  390.         ef = TRUE;
  391.         else {
  392.         Xmd_val(XM_SSIZE,size + 128);
  393.         Xmd_val(XM_SBLK,bk);
  394.         }
  395.     } else if ( ch == NAK ) {
  396.         if ( nk++ > 0 )
  397.         Xmd_val(XM_RETRY,nk);
  398.         fseek(fp,size,SEEK_SET);
  399.         if ( Send_blk(fp,bk) != FALSE )
  400.         ef = TRUE;
  401.         else {
  402.         Xmd_val(XM_SSIZE,size + 128);
  403.         Xmd_val(XM_SBLK,bk);
  404.         }
  405.     } else if ( ch == CAN ) {
  406.             Xmd_msg("Recive Cansel Code !!");
  407.         Soft_Timer(DSP_WAIT);
  408.             break;
  409.         }
  410.         if ( nk >= 5 ) {
  411.             Xmd_msg("ReTry Over Abort !!");
  412.         send_aux(CAN);
  413.         Soft_Timer(DSP_WAIT);
  414.         break;
  415.     }
  416.     }
  417.     fclose(fp);
  418. }
  419. *********/
  420. /* ---------------------------------------------------------------- */
  421.  
  422. void    Down_Xmodem(file)
  423. char    *file;
  424. {
  425.     int     i,j,ch,bk,nk,ef;
  426.     unsigned int ec;
  427.     long    size;
  428.     FILE    *fp;
  429. /* --------------XMODEM 1024/CRC 92/02/17 Pumpkin ----------------- */
  430.     time_t  fsttime,nowtime,*t=NULL;
  431.     int        bufsize = 128,k,sectnum,sectcur;
  432.     unsigned short crcsum;
  433.     UCHAR   tmp[1024];
  434. /**********
  435.     UCHAR   tmp[128];
  436. *********/
  437. /* ---------------------------------------------------------------- */
  438.  
  439.     Xmd_wind("DownLoad",file);
  440.     if ( (fp = fopen(file,"wb")) == NULL ) {
  441.     wrtstr("ファイルが作成出来ません",30,1,0x12);
  442.     return;
  443.     }
  444. /* ----------------- DATA RATE 92/02/17 Pumpkin ----------------- */
  445.     fsttime = time(t);
  446. /* ---------------------------------------------------------------- */
  447.     for ( ef = TRUE,bk = 1,size = 0,nk = 0 ; ; ) {
  448.     if ( kbhit() != 0 ) {
  449.         ch = Get_key(&ec);
  450.         if ( ch == 0x1B || ec == 0x7200 ) {
  451.         Xmd_msg("Abort Xmodem Download !!");
  452.             send_aux(CAN);
  453.         Soft_Timer(DSP_WAIT);
  454.         break;
  455.         }
  456.     }
  457.     for ( i = 0 ; i < 5 ; i++ ) {
  458. /* --------------XMODEM 1024/SUM/CRC 92/02/17 Pumpkin ----------------- */
  459.         if (crcmode==TRUE && (bk==1 || bk==2))  { /* CRC */
  460.         send_aux(CRC);
  461.         } else {
  462.             if ( ef == FALSE )
  463.             send_aux(ACK);
  464.             else if ( Flaing == FALSE )
  465.             send_aux(NAK);
  466.             else {
  467.             send_aux(NAK); send_aux(ACK);
  468.             }
  469.         }
  470. /**************
  471.         if ( ef == FALSE )
  472.         send_aux(ACK);
  473.         else if ( Flaing == FALSE )
  474.         send_aux(NAK);
  475.         else {
  476.         send_aux(NAK); send_aux(ACK);
  477.         }
  478. **************/
  479. /* ---------------------------------------------------------------- */
  480.         if ( (ch = Recive()) != ERR ) 
  481.         break;
  482.         Xmd_val(XM_TMOVR,i);
  483.     }
  484.  
  485.     if ( i >= 5 ) {
  486.         Xmd_msg("Time Over Abort !!");
  487.         Soft_Timer(DSP_WAIT);
  488.         break;
  489.     }
  490.  
  491.     if ( ch == EOT ) {
  492.         Xmd_msg("End of DownLoad !!");
  493.         if ( Flaing == FALSE )
  494.         send_aux(ACK);
  495.         break;
  496.     } else if ( ch == CAN ) {
  497.             Xmd_msg("Recive Cansel Code !!");
  498.         Soft_Timer(DSP_WAIT);
  499.             break;
  500. /* --------------XMODEM 1024/SUM/CRC 92/02/17 Pumpkin ----------------- */
  501.         } else if ( ch == SOH || ch == STX ) {
  502.         bufsize = (ch == SOH) ? 128 : 1024;
  503.         if (bk==1) {
  504.             if (ch == SOH && crcmode==TRUE) Xmd_msg("X-Modem 128/CRC");
  505.             if (ch == STX && crcmode==TRUE) Xmd_msg("X-Modem 1024/CRC");
  506.             if (ch == SOH && crcmode==FALSE) Xmd_msg("X-Mmodem 128/SUM");
  507.             if (ch == STX && crcmode==FALSE) Xmd_msg("X-Modem 1024/SUM");
  508.           }
  509.  
  510.         sectcur = Recive();
  511.             if ( (sectcur + Recive()) != 0xff ) {
  512.                Xmd_msg("PacNo. SUM Error");
  513.         goto ERROR;
  514.         }
  515.             if ( sectcur != (bk & 0xff) ) {
  516.         sprintf((char *)tmp,"PacNo. Err rcv=%4d cal=%4d",sectcur,bk);
  517.                Xmd_msg((char *)tmp);
  518.         goto ERROR;
  519.         }
  520.         if ( Recive_str(tmp,bufsize) != FALSE ) {
  521.                Xmd_msg("Data Read Error");
  522.         goto ERROR;
  523.         }
  524.         for ( crcsum = j = i = 0 ; i < bufsize ; i++ ) {
  525.         if (crcmode==TRUE)  { /* CRC */
  526.                 crcsum = (crcsum<<B) ^ crctab[(crcsum>>(W-B)) ^ tmp[i]];
  527.         } else {        /* checksum */
  528.              j += tmp[i]; j &= 0xff;
  529.         }
  530.         }
  531.  
  532.         if (crcmode==TRUE) { /* CRC */
  533.         k = Recive(); k = (k<<8) | Recive();
  534.             if ( k != crcsum ) {
  535.             sprintf((char *)tmp,"CRC Err rcv=%4X cal=%4X",k,crcsum);
  536.                     Xmd_msg((char *)tmp);
  537.             goto ERROR;
  538.         }
  539.         } else {
  540.             if ( Recive() != j ) {
  541.                     Xmd_msg("Check SUM Error");
  542.             goto ERROR;
  543.         }
  544.         }
  545.         
  546.  
  547.         fwrite(tmp,1,bufsize,fp);
  548.         size += bufsize;
  549.  
  550.         nowtime = time(t);
  551.         if ((nowtime-fsttime) != 0) {
  552.             Xmd_val(XM_RATE,size/(nowtime-fsttime));
  553.         }
  554.         Xmd_val(XM_ERTIME,(nowtime-fsttime));
  555.  
  556.         Xmd_val(XM_RSIZE,size);
  557.         Xmd_val(XM_RBLK,bk);
  558.         ef = FALSE;
  559.         nk = 0;
  560.         bk ++;
  561.         continue;
  562.     }
  563.  
  564.     sprintf((char *)tmp,"Undefined Code %2X     ",ch);
  565.     Xmd_msg(tmp);
  566.  
  567. ERROR:  Recive_str(tmp,bufsize); /* Dummy */
  568.  
  569. /**********
  570.         } else if ( ch == SOH ) {
  571.             if ( Recive() != (bk & 0xff) )
  572.         goto ERROR;
  573.             if ( (255 - Recive()) != (bk & 0xff) )
  574.         goto ERROR;
  575.         if ( Recive_str(tmp,128) != FALSE )
  576.         goto ERROR;
  577.         for ( j = i = 0 ; i < 128 ; i++,j &= 0xff )
  578.         j += tmp[i];
  579.         if ( Recive() != j )
  580.         goto ERROR;
  581.  
  582.         fwrite(tmp,1,128,fp);
  583.         size += 128;
  584.         Xmd_val(XM_RSIZE,size);
  585.         Xmd_val(XM_RBLK,bk);
  586.         ef = FALSE;
  587.         nk = 0;
  588.         bk++;
  589.         continue;
  590.     }
  591.  
  592. ERROR:  Recive_str(tmp,128);    /+ Dummy +/
  593. *********/
  594. /* ---------------------------------------------------------------- */
  595.  
  596.     ef = TRUE;
  597.     Xmd_val(XM_RETRY,++nk);
  598.         if ( nk >= 5 ) {
  599.             Xmd_msg("ReTry Over Abort !!");
  600.         send_aux(CAN);
  601.         Soft_Timer(DSP_WAIT);
  602.         break;
  603.     }
  604.     }
  605.     fclose(fp);
  606. }
  607.  
  608. void    Down_Ymodem()
  609. {
  610.     int     i,j,ch,bk,nk,ef;
  611.     unsigned int ec;
  612.     time_t  fsttime,nowtime,*t=NULL;
  613.     long    size, filesize, modtime, filemode;
  614.     FILE    *fp;
  615.     int        bufsize = 128,k,sectnum,sectcur;
  616.     unsigned short crcsum;
  617.     char    tmp[1024],file[128],*p;
  618.  
  619.     Xmd_wind("DownLoad","");
  620.     for ( ef = TRUE,bk = 0,size = 0,nk = 0 ; ; ) {
  621.     if ( kbhit() != 0 ) {
  622.         ch = Get_key(&ec);
  623.         if ( ch == 0x1B || ec == 0x7200 ) {
  624.         Xmd_msg("Abort Ymodem Download !!");
  625.             send_aux(CAN);
  626.         Soft_Timer(DSP_WAIT);
  627.         break;
  628.         }
  629.     }
  630.     for ( i = 0 ; i < 5 ; i++ ) {
  631.         if (bk==0 || bk==1)  { /* CRC */
  632.         send_aux(CRC);
  633.         } else {
  634.             if ( ef == FALSE )
  635.             send_aux(ACK);
  636.             else if ( Flaing == FALSE )
  637.             send_aux(NAK);
  638.             else {
  639.             send_aux(NAK); send_aux(ACK);
  640.             }
  641.         }
  642.         if ( (ch = Recive()) != ERR ) 
  643.         break;
  644.         Xmd_val(XM_TMOVR,i);
  645.     }
  646.  
  647.     if ( i >= 5 ) {
  648.         Xmd_msg("Time Over Aobrt !!");
  649.         Soft_Timer(DSP_WAIT);
  650.         break;
  651.     }
  652.  
  653.     if ( ch == EOT ) {
  654.         Xmd_msg("End of DownLoad !!");
  655.         if ( Flaing == FALSE )
  656.             send_aux(ACK); send_aux(ACK); send_aux(ACK);
  657.         break;
  658.     } else if ( ch == CAN ) {
  659.             Xmd_msg("Recive Cansel Code !!");
  660.         Soft_Timer(DSP_WAIT);
  661.             break;
  662.         } else if ( ch == SOH || ch == STX ) {
  663.         bufsize = (ch == SOH) ? 128 : 1024;
  664.  
  665.         sectcur = Recive();
  666.             if ( (sectcur + Recive()) != 0xff ) {
  667.                Xmd_msg("PacNo. SUM Error");
  668.         goto ERROR;
  669.         }
  670.             if ( sectcur != 0 && sectcur != (bk & 0xff) ) {
  671.         sprintf((char *)tmp,"PacNo. Err rcv=%4d cal=%4d",sectcur,bk);
  672.                Xmd_msg(tmp);
  673.         goto ERROR;
  674.         }
  675.         if ( Recive_str(tmp,bufsize) != FALSE ) {
  676.                Xmd_msg("Data Read Error");
  677.         goto ERROR;
  678.         }
  679.         for ( crcsum = i = 0 ; i < bufsize ; i++ ) {
  680.                crcsum = (crcsum<<B) ^ crctab[(crcsum>>(W-B)) ^ tmp[i]];
  681.         }
  682.  
  683.         /* CRC */
  684.         k = Recive(); k = (k<<8) | Recive();
  685.         if ( k != crcsum ) {
  686.                 Xmd_msg("CRC Error");
  687.         goto ERROR;
  688.         }
  689.  
  690.  
  691.         if (sectcur == 0) {
  692.         strcpy(file, (char *)tmp);
  693.         p = tmp + strlen(tmp) + 1;
  694.         sscanf(p, "%ld%lo%o", &filesize, &modtime, &filemode);
  695.  
  696.         Xmd_wind("DownLoad",file);
  697.         Xmd_val(XM_FSIZE,filesize);
  698.         Xmd_msg("Y-Modem/1024");
  699.         i = filesize / 1024;
  700.         i += ((filesize - i * 1024)+127) / 128;
  701.             Xmd_val(XM_TBLK,i);
  702.  
  703.             if ( (fp = fopen(file,"wb")) == NULL ) {
  704.             wrtstr("ファイルが作成出来ません",30,1,0x12);
  705.                 send_aux(CAN); send_aux(CAN); send_aux(CAN);
  706.                 Soft_Timer(DSP_WAIT);
  707.                 break;
  708.         }
  709.             fsttime = time(t);
  710.  
  711.         } else {
  712.             if (filesize >= (size + bufsize)) {
  713.                 fwrite(tmp,1,bufsize,fp);
  714.                    size += bufsize;
  715.             }else{
  716.                 fwrite(tmp,1,(filesize - size),fp);
  717.                    size = filesize;
  718.             }
  719.         }
  720.  
  721.         nowtime = time(t);
  722.         if ((nowtime-fsttime) != 0) {
  723.             Xmd_val(XM_RATE,size/(nowtime-fsttime));
  724.         }
  725.         Xmd_val(XM_ERTIME,(nowtime-fsttime));
  726.         Xmd_val(XM_RSIZE,size);
  727.         Xmd_val(XM_RBLK,bk);
  728.         ef = FALSE;
  729.         nk = 0;
  730.         bk ++;
  731.         continue;
  732.     }
  733.  
  734.     sprintf((char *)tmp,"Undefined Code %2X     ",ch);
  735.     Xmd_msg(tmp);
  736.  
  737. ERROR:  Recive_str(tmp,bufsize); /* Dummy */
  738.     ef = TRUE;
  739.     Xmd_val(XM_RETRY,++nk);
  740.         if ( nk >= 5 ) {
  741.             Xmd_msg("ReTry Over Abort !!");
  742.         send_aux(CAN);
  743.         Soft_Timer(DSP_WAIT);
  744.         break;
  745.     }
  746.     }
  747.     fclose(fp);
  748. }
  749.  
  750. /**************************
  751.     Auto Login
  752. **************************/
  753. int    htob(ch)
  754. int     ch;
  755. {
  756.     int     i=0;
  757.  
  758.     if ( ch >= 'a' && ch <= 'z' )
  759.     ch &= 0xDF;
  760.     if ( '0' <= ch && ch <= '9' )
  761.         i = ch - '0';
  762.     else if ( 'A' <= ch && ch <= 'F' )
  763.         i = ch - 'A' + 10;
  764.     return i;
  765. }
  766. int    Wait_recive(tick)
  767. int    tick;
  768. {
  769.     int     len,ch;
  770.     unsigned int st;
  771.     time_t  l,s;
  772.  
  773.     time(&l); l += tick;
  774.     do {
  775.     RSB_Read(port,&len);
  776.         if ( len > 0 ) {
  777.         RSB_Receive(port,&ch,&st);
  778.         BakPut(ch); Dsp_vram(cvram);
  779.         return ch;
  780.     }
  781.     time(&s);
  782.     } while ( kbhit() == 0 && s < l );
  783.     return ERR;
  784. }
  785. void    RS_Sleep(tick)
  786. int    tick;
  787. {
  788.     int     len,ch;
  789.     unsigned int st;
  790.     time_t  l,s;
  791.  
  792.     time(&l); l += tick;
  793.     do {
  794.     RSB_Read(port,&len);
  795.         if ( len > 0 ) {
  796.         while ( len-- > 0 ) {
  797.             RSB_Receive(port,&ch,&st);
  798.             BakPut(ch);
  799.         }
  800.         Dsp_vram(cvram);
  801.     }
  802.     time(&s);
  803.     } while ( kbhit() == 0 && s < l );
  804. }
  805. int    cmpstr(arg)
  806. char    *arg;
  807. {
  808.     int     ch,wt;
  809.     register char    *p;
  810.  
  811.     for ( p = arg,wt = 0 ; isdigit(*p) ; p++ )
  812.     wt = wt * 10 + *p - '0';
  813.     if ( *p == ',' && wt > 0 )
  814.     arg = p + 1;
  815.     else
  816.     wt = 30;
  817.  
  818.     for ( p=arg ; *p != ']' ; ) {
  819.         if ( (ch=Wait_recive(wt)) == ERR )
  820.             return ERR;
  821.         if ( ch == (*p & 0xff) )
  822.             p++;
  823.         else
  824.             p=arg;
  825.     }
  826.     return FALSE;
  827. }
  828. int    cmpmac(arg)
  829. char    *arg;
  830. {
  831.     int     ch,wt;
  832.     register char    *p;
  833.  
  834.     for ( p = arg,wt = 0 ; isdigit(*p) ; p++ )
  835.     wt = wt * 10 + *p - '0';
  836.     if ( *p == ',' && wt > 0 )
  837.     arg = p + 1;
  838.     else
  839.     wt = 5;
  840.  
  841.     for ( p=arg ; *p != '}' ; ) {
  842.         if ( (ch=Wait_recive(wt)) == ERR )
  843.             return ERR;
  844.         if ( ch == (*p & 0xff) )
  845.             p++;
  846.         else
  847.             p=arg;
  848.     }
  849.     return FALSE;
  850. }
  851. int    runlog(arg)
  852. register char    *arg;
  853. {
  854.     int     ch;
  855.     char    *p;
  856.     char    *adr=NULL;
  857.  
  858.     for ( ; *arg != '\0' ; arg++ ) {
  859.         switch(*arg) {
  860.             case '<':
  861.                 send_aux(CR);
  862.                 break;
  863.             case '>':
  864.                 while ( (ch=Wait_recive(30)) != CR ) {
  865.             if ( ch == ERR )
  866.             return ERR;
  867.                     if ( kbhit() != 0 )
  868.                         return TRUE;
  869.                 }
  870.                 break;
  871.             case '$':
  872.                 send_aux( htob(*(++arg)) << 4 | htob(*(++arg)) );
  873.                 break;
  874.             case '\\':
  875.                 send_aux(*(++arg));
  876.                 break;
  877.             case '*':
  878.                 RS_Sleep(2);
  879.                 break;
  880.             case '?':
  881.         adr = arg;
  882.         break;
  883.             case '@':
  884.         adr = NULL;
  885.         break;
  886.             case '[':
  887.                 if ( cmpstr(++arg) != FALSE )
  888.                     return ERR;
  889.                 while ( *arg != ']' ) arg++;
  890.                 break;
  891.             case '{':
  892.         if ( adr == NULL ) {
  893.                     for ( p = arg ; *p != '?' && *p != '\0' ; p++ )
  894.             if ( *p == '?' )
  895.                 adr = p;
  896.             else
  897.                 return ERR;
  898.         }
  899.                 if ( cmpmac(++arg) != FALSE ) {
  900.             if ( kbhit() != 0 )
  901.             return ERR;
  902.             arg = adr;
  903.         } else
  904.                     while ( *arg != '}' ) arg++;
  905.                 break;
  906.             default:
  907.                 send_aux(*arg);
  908.                 break;
  909.         }
  910.         if ( kbhit() != 0 )
  911.             return TRUE;
  912.     }
  913.     return FALSE;
  914. }
  915. char    *Auto_menu[21]={ NULL };
  916. char    *Auto_para[21];
  917.  
  918. void    Auto_log()
  919. {
  920.     static int  no=ERR;
  921.  
  922.     if ( Auto_menu[0] == NULL )
  923.     goto ENDOF;
  924.  
  925.     if ( Sel_menu(Auto_menu,20,2,&no) != FALSE )
  926.     goto ENDOF;
  927.  
  928.     wrtstr(SPCSTR,30,1,0x1F);
  929.     if ( runlog(Auto_para[no]) == ERR )
  930.     wrtstr("オ-トを中断しました",30,1,0x15);
  931.  
  932. ENDOF:
  933.     Dsp_vram(cvram);
  934.     Dsp_free();
  935. }
  936.  
  937. char    *Auto_log_file="WINK.DEF";
  938.  
  939. void    Auto_log_init()
  940. {
  941.     int     i,mx=0;
  942.     FILE    *fp;
  943.     char    *p,*s,*n;
  944.     char    tmp[256];
  945.     char    work[4096];
  946.  
  947.     if ( (p = getenv("WINKAUTO")) != NULL )
  948.     Auto_log_file = p;
  949.  
  950.     if ( (fp = fopen(Auto_log_file,"r")) == NULL )
  951.     return;
  952.  
  953.     while ( (p = fgets(tmp,256,fp)) != NULL ) {
  954.     while ( isspace(*p) ) p++;
  955.     while ( p != NULL && *p == '#' ) {
  956.         for ( s = ++p ; *s != '\n' && *s != '\0' ; s++ );
  957.         *s = '\0';
  958.         if ( (n = Auto_menu[mx] = (char *)malloc(22)) == NULL )
  959.         goto ENDOF;
  960.         for ( i = 0 ; i < 20 && *p != '\0' ; i++ )
  961.         *(n++) = *(p++);
  962.         for ( ; i < 20 ; i++ )
  963.         *(n++) = ' ';
  964.         *n = '\0';
  965.         for ( s = work ; (p = fgets(tmp,256,fp)) != NULL ; ) {
  966.         while ( isspace(*p) ) p++;
  967.         if ( *p == '#' )
  968.             break;
  969.         while ( *p != '\n' && *p != '\0' )
  970.             *(s++) = *(p++);
  971.         }
  972.         *s = '\0';
  973.         if ( (Auto_para[mx] = (char *)malloc(strlen(work)+1)) == NULL )
  974.         goto ENDOF;
  975.         strcpy(Auto_para[mx],work);
  976.         if ( ++mx >= 20 )
  977.             goto ENDOF;
  978.     }
  979.     }
  980. ENDOF:
  981.     fclose(fp);
  982.     Auto_menu[mx] = NULL;
  983. }
  984.